#include "MoneyMarketWidget.h"
#include "CapitalMarketFunds.h"
#include "CapitalMarketAssets.h"
#include "CapitalMarketSettings.h"
#include "MMOpenMarketOperator.h"
#include "MMOrderSettingForm.h"
#include "CapitalMarketCNEX.h"
#include "../StringResource.h"
#include <core/StyleMgr.h>
#include <core/ImageMgr.h>
#include <widgets/SDialog.h>
#include <widgets/SImageButton.h>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QColor>
#include <qstylepainter.h>
#include <QCheckBox>
#include <QListWidget>
#include <QVector>
#include <QSplitter>
#include "widgets/SDialog.h"

namespace
{
	const int lineHeight = StyleMgr::instance().size("ButtonHeight");
	const int blockHeight = lineHeight * 5;
    const int kStrech = 10;
}

MoneyMarketWidget::MoneyMarketWidget(QWidget* parent)
	: QFrame(parent)
{
#define MM_ADD_CHILD(CLASS, str, hLayout){ \
		CLASS* child = new CLASS(str, this);\
		child->setFixedHeight(blockHeight); \
		m_vctChildren.push_back(child); \
		hLayout->addWidget(child);\
	}

    CapitalMarketSettings::instance(CapitalMarketSettings::Funds).loadRecord();
    CapitalMarketSettings::instance(CapitalMarketSettings::Assets).loadRecord();

	QVBoxLayout* mainLayout = new QVBoxLayout(this);
	mainLayout->setContentsMargins(0, 0, 0, 0);
	mainLayout->setSpacing(0);

    /*QHBoxLayout* hLayout = new QHBoxLayout();
    hLayout->setContentsMargins(0, 0, 0, 0);
    hLayout->setSpacing(1);
    mainLayout->addLayout(hLayout);*/

    QSplitter* splitter = new QSplitter(this);
    splitter->setObjectName(QString::fromUtf8("splitter"));
    splitter->setHandleWidth(2);
    mainLayout->addWidget(splitter);

    {
        money_market = new CapitalMarketFunds(NewStringTable::strMoneyMarketWidget(7), splitter);
        splitter->addWidget(money_market);
        SImageButton* setting = money_market->findChild<SImageButton*>(SDialogTitle::kbtnSettingObjName);
        if (setting) {
            connect(setting, &SImageButton::clicked, this, &MoneyMarketWidget::onSettingClick);
        }
    }
    {
        asset_market = new CapitalMarketAssets(NewStringTable::strMoneyMarketWidget(8), splitter);
        splitter->addWidget(asset_market);
        SImageButton* setting = asset_market->findChild<SImageButton*>(SDialogTitle::kbtnSettingObjName);
        if (setting) {
            connect(setting, &SImageButton::clicked, this, &MoneyMarketWidget::onSettingClick);
        }
    }

    {
        m_wndOMO = new MMOpenMarketOperator(NewStringTable::strMoneyMarketWidget(6), this);//公开市场操作
        mainLayout->addWidget(m_wndOMO);
        QWidget* title = m_wndOMO->findChild<QWidget*>(SDialogTitle::kName);
        QHBoxLayout* titleLayout = qobject_cast<QHBoxLayout*>(title->layout());
        if (titleLayout) {
            m_omo_fold = new SImageButton(title, "widgets_dropdown_up");
            titleLayout->insertWidget(0, m_omo_fold);

            connect(m_omo_fold, &SImageButton::clicked, this, &MoneyMarketWidget::onFoldClicked);
        }
    }

    {
        m_CNEX = new CapitalMarketCNEX(NewStringTable::strMoneyMarketWidget(9), this);
        mainLayout->addWidget(m_CNEX);
        QWidget* title = m_CNEX->findChild<QWidget*>(SDialogTitle::kName);
        QHBoxLayout* titleLayout = qobject_cast<QHBoxLayout*>(title->layout());
        if (titleLayout) {
            m_cnex_fold = new SImageButton(title, "widgets_dropdown_up");
            titleLayout->insertWidget(0, m_cnex_fold);

            connect(m_cnex_fold, &SImageButton::clicked, this, &MoneyMarketWidget::onFoldClicked);
        }
    }

	// 	m_ui.setupUi(this);

	QString styleSheet = QString("MoneyMarketWidget {background-color:#%1}")
		.arg(StyleMgr::instance().color("BasicPlate").rgb(), 0, 16);
// 	QString styleSheet = QString("background-color:#%1")
// 		.arg(StyleMgr::instance().color("BasicPlate").rgb(), 0, 16);
	setStyleSheet(styleSheet);

    mainLayout->setStretch(0, kStrech);
    mainLayout->setStretch(1, kStrech/2);
    mainLayout->setStretch(2, kStrech/2);
}

void MoneyMarketWidget::resetStretch()
{
    int divider = 0;
    QVBoxLayout* mainLayout = dynamic_cast<QVBoxLayout*>(this->layout());
    if (m_wndOMO->is_unfold()) {
        divider += 1;
    } else {
        mainLayout->setStretch(1, 0);
    }
    if (m_CNEX->is_unfold()) {
        divider += 1;
    } else {
        mainLayout->setStretch(2, 0);
    }

    if (divider != 0){
        if (m_wndOMO->is_unfold()) {
            mainLayout->setStretch(1, kStrech/divider);
        }
        if (m_CNEX->is_unfold()) {
            mainLayout->setStretch(2, kStrech/divider);
        }
    }

}

void MoneyMarketWidget::onFoldClicked() {
    if (sender() == m_omo_fold) {
        if (m_wndOMO->is_unfold()) {
            m_wndOMO->fold();
            m_omo_fold->setImgId("widgets_dropdown_down");
        } else {
            m_wndOMO->unfold();
            m_omo_fold->setImgId("widgets_dropdown_up");
        }
    } else if (sender() == m_cnex_fold) {
        if (m_CNEX->is_unfold()) {
            m_CNEX->fold();
            m_cnex_fold->setImgId("widgets_dropdown_down");
        } else {
            m_CNEX->unfold();
            m_cnex_fold->setImgId("widgets_dropdown_up");
        }
    } else {
        return;
    }

    resetStretch();
}

void MoneyMarketWidget::paintEvent(QPaintEvent* e)
{
	QFrame::paintEvent(e);
	QRect r = rect();
	r.setHeight(24);

	QStylePainter painter(this);
	painter.setPen(StyleMgr::instance().color("TextNormal"));
	painter.drawText(r, tr("资金"), QTextOption(Qt::AlignCenter));
}

struct moved_item {
    MMOrderSettingForm::ButtonId direction;
    QListWidget* from;
    QListWidget* to;
    char step;
    //explicit moved_item(const char* d, QListWidget* f, QListWidget* t, char s):direction(d), from(f), to(t), step(s) {}
};

void load_orders(QListWidget *left, QListWidget *right, const std::vector<int>& current_order, const std::vector<int>& all_order) {
    left->clear();
    right->clear();
    for (const auto& id : current_order) {
        QListWidgetItem *item = new QListWidgetItem(CapitalMarketSettings::getName(id), right, id + QListWidgetItem::UserType);
        item->setCheckState(Qt::Unchecked);
        right->addItem(item);
    }

    for (const auto& id : all_order) {
        if (current_order.end() != std::find(current_order.begin(), current_order.end(), id))
            continue;
        QListWidgetItem *item = new QListWidgetItem(CapitalMarketSettings::getName(id), left, id + QListWidgetItem::UserType);
        item->setCheckState(Qt::Unchecked);
        left->addItem(item);
    }
};

void MoneyMarketWidget::onSettingClick(int i)
{
    MMOrderSettingForm * form = new MMOrderSettingForm(nullptr);

    const CapitalMarketSettings::CapitalMarketType type = money_market->isAncestorOf((QWidget *)sender()) ? CapitalMarketSettings::Funds : CapitalMarketSettings::Assets;

    SDialog dlg;
    dlg.setTitle((type == CapitalMarketSettings::Funds) ? tr("资金显示与顺序设置") : tr("资产显示与顺序设置"));
    dlg.setContent(form);
    dlg.resize(540, 440);
    {
        QListWidget *left = new QListWidget(form);
        QListWidget *right = new QListWidget(form);
        right->setDefaultDropAction(Qt::IgnoreAction);
        right->setDragDropMode(QAbstractItemView::InternalMove);
        form->setContentWidget(left, right);

        const std::vector<int> all_order = CapitalMarketSettings::instance(type).getAllOrder();
        const std::vector<int> current_order = CapitalMarketSettings::instance(type).getOrder();
        const std::vector<int> default_order = CapitalMarketSettings::instance(type).getDefaultOrder();

        load_orders(left, right, current_order, all_order);
        form->setStatistic(QString("%1 / %2").arg(current_order.size()).arg(all_order.size()));

        connect(form, &MMOrderSettingForm::buttonClicked, this, [&dlg, &all_order, &default_order, form, left, right](MMOrderSettingForm::ButtonId button_id, bool checked) {
            switch(button_id) {
            case MMOrderSettingForm::reset: {
                load_orders(left, right, default_order, all_order);
                form->setStatistic(QString("%1 / %2").arg(default_order.size()).arg(all_order.size()));
            } break;
            case MMOrderSettingForm::confirm: {
                dlg.accept();
            } break;
            case MMOrderSettingForm::cancel: {
                dlg.reject();
            } break;
            default: {
                const QVector<moved_item> move_ops = {
                    {MMOrderSettingForm::to_right, left, right, (char)1},
                  {MMOrderSettingForm::to_left, right, left, (char)1},
                  {MMOrderSettingForm::to_upper, right, right, (char)-1},
                  {MMOrderSettingForm::to_lower, right, right, (char)1},
                  {MMOrderSettingForm::to_top, right, right, (char)-127},
                  {MMOrderSettingForm::to_bottom, right, right, (char)127}
                };

                auto iter = std::find_if(move_ops.begin(), move_ops.end(), [button_id](const moved_item& item){
                    return button_id == item.direction;
                });
                if (iter != move_ops.end()) {
                    QVector<QListWidgetItem *> items;
                    items.reserve(iter->from->count());
                    int first{-1}, last{-1};
                    // take from "from"
                    for (int i = iter->from->count(); i > 0; --i) {
                        QListWidgetItem *item = iter->from->item(i-1);
                        if (item && (item->checkState() == Qt::Checked)) {
                            first = i-1;
                            if (items.isEmpty()) {
                                last = i-1;
                            }
                            items.insert(0, iter->from->takeItem(i-1));
                        }
                    }
                    if (items.isEmpty())
                        return;
                    // insert into "to"
                    int insert_at = 0;
                    if (iter->from != iter->to)
                        insert_at = 1 + iter->to->currentRow();
                    else {
                        insert_at = iter->step + first;//(iter->step < 0 ? first : last);
                        insert_at = std::max(0, insert_at);
                        insert_at = std::min(iter->to->count(), insert_at);
                    }
                    for (auto *item : items) {
                        iter->to->insertItem(insert_at++, item);
                    }

                    form->setStatistic(QString("%1 / %2").arg(right->count()).arg(right->count() + left->count()));
                }
            } break;
            }
        });

        if (SDialog::Accepted == dlg.exec()) {
            std::vector<int> result;
            for(int i = 0; i < right->count(); ++i) {
                QListWidgetItem *item = right->item(i);
                if (item) {
                    result.push_back( item->type() - QListWidgetItem::UserType );
                }
            }

            CapitalMarketSettings::instance(type).setOrder(std::move(result));
            CapitalMarketSettings::instance(type).saveRecord();
        }
    }


}
